package org.json;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JsonObjectifier {

    public static Object get(JSONObject currentNode, String name) {
        try {
            return currentNode.get(name);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    public static Object get(JSONArray jsonArray, int index) {
        try {
            return jsonArray.get(index);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    public static Iterable iterable(final JSONArray jsonArray) {
        return new Iterable() {
            @Override
            public Iterator iterator() {
        return new JSONArrayIterator(jsonArray);
    }
        };
    }

    public static boolean equals(JSONObject a, JSONObject b) {
        return a.toString().equals(b.toString());
    }

    public static JsonEquableList jsonEquable(List<Object> list) {
        return new JsonEquableList(list);
    }

    private static class JSONArrayIterator implements Iterator {
        private JSONArray jsonArray;
        private int index = 0;

        public JSONArrayIterator(JSONArray jsonArray) {
            this.jsonArray = jsonArray;
        }

        @Override public boolean hasNext() {
            return index < jsonArray.length();
        }

        @Override public Object next() {
            return get(jsonArray, index++);
        }

        @Override public void remove() {
            throw new UnsupportedOperationException("Not implemented yet");
        }
    }

    private static class EquableJSONObject {
        private JSONObject delegate;

        public EquableJSONObject(JSONObject delegate) {
            this.delegate = delegate;
        }

        @Override public boolean equals(Object obj) {
            return obj instanceof EquableJSONObject && equals((EquableJSONObject) obj);
        }

        private boolean equals(EquableJSONObject equableJSONObject) {
            return JsonObjectifier.equals(delegate, equableJSONObject.delegate);
        }
    }

    static class JsonEquableList extends ArrayList<Object> {

        public JsonEquableList(List<Object> list) {
            super(list);
        }

        @Override public Object get(int index) {
            Object value = super.get(index);
            return value instanceof JSONObject ? new EquableJSONObject((JSONObject) value) : value;
        }
    }
}
